package model;


import hci.ChatGui;

import java.io.File;
import java.util.ArrayList;

import observerNotification.ObserverNotification;

import main.ChatSystem;


/**
 * Saves conversations in the model
 * 
 * <p>
 * <ul>
 * <li>Project: 	ChatSystemG3</li>
 * <li>Called by: 	Model</li>
 * </ul>
 * </p>
 * 
 * @author COMBES Nicolas - LECHANTRE Arnaud
 */
public class Conversation {

	/**
	 * Enumeration describing the different transfert state in which the conversation can be
	 */
	public static enum enumTransferState {sending, nonSending};
	
	/**
	 * List containing remote users names
	 */
	private ArrayList<RemoteUser> users;
	/**
	 * List containing sent messages
	 */
	private ArrayList<ModelMessage> messages;			
	/**
	 * Unique identifier of the conversation
	 */
	private int id;										
	/**
	 * Variable containing the conversation tranfer state, usefull to enable only one transfer at a time by conversation
	 */
	private enumTransferState convState;				
	
	
	/**
	 * Construct
	 * 
	 * @param users list containing remote users to add to conversation
	 * @param id unique identifier of the conversation
	 */
	public Conversation(ArrayList<RemoteUser> users, int id) {
		super();
		this.users = users;
		this.messages = new ArrayList<ModelMessage>();
		this.id = id;
	}
	
	/**
	 * Construct 
	 * 
	 * @param nextConvNum unique identifier of the conversation to be created
	 * @param user name of the  user to add to conversation
	 */
	public Conversation(Integer id, RemoteUser user) {
		super();
		this.users = new ArrayList<RemoteUser>();
		this.users.add(user);
		this.messages = new ArrayList<ModelMessage>();
		this.id = id;
		if(ChatSystem.debugMode)System.out.println("Model.conversation: creation of conversation number "+ this.id);
	}

	/**
	 * addMessage
	 * @param u message sender
	 * @param message message to add to conversation
	 */
	public void addMessage(User u, String message){
		this.messages.add(new ModelTextMessage(u, message));
	}

	/**
	 * hasRemoteUser
	 * @param username a remote user name
	 * @return true if there is a remote user in the conversation whose name is equal to username
	 */
	public boolean hasRemoteUser(String username) {
		return this.users.size()==1 && this.users.get(0).getName().equals(username);
	}

	/**
	 * hasRemoteUsers
	 * @param username : names of users we want to know if they are in this conversation
	 * @return true if the conversation contain all the remote users given and only them
	 */
	public boolean hasRemoteUsers(String[] username) {
		if(username.length!=this.users.size()){
			//If the array do not have the same number of user that the conversation 
			return false;	//the answer is obviously false
		}
		boolean foundAnAbsent = false;
		int i=0;
		while (!foundAnAbsent && i<username.length){
			foundAnAbsent = !this.hasRemoteUser(username[i]);
			i++;
		}
		return !foundAnAbsent;
	}
	/**
	 * getStringOfUsers
	 * @return names off all the remote users in the conversation separated by a ' '
	 */
	public String getStringOfUsers() {
		String s = "";
		for(int i=0;i<this.users.size();i++){
			s+=this.users.get(i).getName()+" ";
		}
		return s;
	}
	
	/**
	 * getID
	 * @return the unique identifier of the conversation
	 */
	public int getID(){
		return this.id;
	}

	/**
	 * getUserList
	 * @return the list of the users in the conversation
	 */
	public String[] getUserList() {
		String s[]=new String[this.users.size()];
		for(int i=0;i<this.users.size();i++){
			s[i]=this.users.get(i).getName();
		}
		
		return s;
	}
	
	/**
	 * getUser
	 * @return the name of the first remote user added to the conversation only
	 */
	public RemoteUser getUser(){
		return this.users.get(0);
	}

	/**
	 * addFileMessage
	 * @param user sender of the file
	 * @param file file to be sent
	 * @throws Exception 
	 */
	public void addFileMessage(User user, File file) throws Exception {
		if(this.convState==Conversation.enumTransferState.sending){
			throw new Exception (ChatGui.strings.getString("errorTooManyTransfertInConversation"));
		} else {
			this.messages.add(new ModelFileMessage(user, file));
			this.convState=Conversation.enumTransferState.sending;
		}
	}

	/**
	 * setAcceptedStateToFile
	 * @param fileName name of the file
	 * @param downloadLink path to save the file, null if user is the sender
	 * @param accept user's answer (true if accepted, false if refused)
	 */
	public void setAcceptedStateToFile(String fileName, File downloadLink, boolean accept) {
		//parcours de message
		for(int i =this.messages.size()-1; i>=0;i--){
			//si file message
			if(this.messages.get(i).getClass().equals(ModelFileMessage.class) 
					&& ((ModelFileMessage) this.messages.get(i)).getFile().getName().equals(fileName)){
				((ModelFileMessage)this.messages.get(i)).setAccepted(accept, downloadLink);
			}
		}
	}

	/**
	 * getFile
	 * @param fileName name of the file to search and get in the discussion
	 * @return the first file named like filename found (starting by the end of the messages list)
	 */
	public File getFile(String fileName) {
		int i=this.messages.size()-1;
		File file = null;
		while(i>=0 && file==null){
			//si file message
			if(this.messages.get(i).getClass().equals(ModelFileMessage.class) 
					&& ((ModelFileMessage) this.messages.get(i)).getFile().getName().equals(fileName)){
				file=((ModelFileMessage) this.messages.get(i)).getFile();
			}
			i--;
		}
		return file;
	}

	/**
	 * Changes the state of the conversation to nonSending
	 */
	public void endFileTransfer() {
		this.convState=Conversation.enumTransferState.nonSending;
	}

	
	
}
